Add MZ twin support to adjacency matrix via twinID column#116
Merged
smasongarrison merged 6 commits intomztwinsfrom Feb 11, 2026
Merged
Add MZ twin support to adjacency matrix via twinID column#116smasongarrison merged 6 commits intomztwinsfrom
smasongarrison merged 6 commits intomztwinsfrom
Conversation
Implement addMZtwins() which redirects one MZ co-twin's parent links to point to the other twin before adjacency matrix construction. This produces isPar[twin2, twin1] = 1.0 in the sparse matrix (two 0.5 entries summed), so path tracing yields relatedness 1 between MZ pairs. Users provide a twinID column (and optionally zygosity) and pass mz_twins=TRUE to ped2add()/ped2com(). DZ twins are left unchanged when zygosity column is present. https://claude.ai/code/session_01P3RQTYpWtAtheSqi4aPjR5
The previous approach redirected twin2's parents to twin1 in the pedigree, which inflated twin2's diagonal (1.5 instead of 1.0) and twin2-to-child relatedness (0.75 instead of 0.5). New approach: after path tracing but before tcrossprod, merge twin2's column into twin1's in the r2 matrix. MZ twins share the same genetic source, so this correctly produces: - MZ twin relatedness = 1.0 - Self-relatedness = 1.0 (no inflation) - Parent-child and all downstream values correct - No post-hoc diagonal patching needed https://claude.ai/code/session_01P3RQTYpWtAtheSqi4aPjR5
Both twin columns now get the same normalized values (r2_merged = (col1 + col2) / sqrt(2)) so both twins remain present and contribute equally. Produces the same final relatedness matrix as the zero approach but without erasing one twin from the genetic source matrix. https://claude.ai/code/session_01P3RQTYpWtAtheSqi4aPjR5
Temporarily absorb twin2's column into twin1's before tcrossprod, then copy twin1's row/col back to twin2 afterward. This keeps the computation correct while ensuring neither twin is erased from the final relatedness matrix. https://claude.ai/code/session_01P3RQTYpWtAtheSqi4aPjR5
Treat both "mz" and "MZ" as monozygotic in findMZtwins (zygosity check now uses %in% c("mz","MZ")). Minor formatting tweak to the verbose message. Added unit tests (tests/testthat/test-buildComponent.R) verifying that MZ twins are coded with relatedness 1 when mz_twins=TRUE, that siblings remain 0.5 when mz_twins=FALSE, self-relatedness stays 1, and parent-child relatedness is unchanged.
0945cb9 to
5f113c4
Compare
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## mztwins #116 +/- ##
==========================================
Coverage ? 84.35%
==========================================
Files ? 28
Lines ? 4487
Branches ? 0
==========================================
Hits ? 3785
Misses ? 702
Partials ? 0 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR implements support for modeling monozygotic (MZ) twins in the relatedness matrix by redirecting one twin's parental links to point to the other twin. This causes the adjacency matrix to assign a relatedness of 1.0 between MZ co-twins instead of the default 0.5 for siblings.
Key Changes
New
addMZtwins()function inR/constructAdjacency.R:twinIDcolumn in the pedigreezygositycolumn exists, only modifies pairs where both members havezygosity == "MZ"zygositycolumn exists, assumes alltwinIDpairs are MZmomIDanddadIDto point to the first twinUpdated
ped2com()function inR/buildComponent.R:mz_twinsparameter (defaults to FALSE for backward compatibility)addMZtwins()whenmz_twins = TRUEandtwinIDcolumn existsUpdated
ped2add()function inR/buildComponent.R:mz_twinsparameter and passes it through toped2com()Enhanced documentation:
mz_twinsparameter description inped2com()to explain the new behavioraddMZtwins()functionComprehensive test coverage in
tests/testthat/test-buildComponent.R:mz_twins = TRUEmz_twins = FALSEImplementation Details
The key insight is that by redirecting both a twin's
momIDanddadIDto point to their co-twin, the path tracing algorithm in the adjacency matrix produces two 0.5 entries (one for each parent link) that sum to 1.0, correctly modeling genetic identity between MZ twins. The diagonal fix ensures that the self-relatedness of the redirected twin matches their co-twin's self-relatedness.https://claude.ai/code/session_01P3RQTYpWtAtheSqi4aPjR5